#include "sdlqtrgb.h"
#include <SDL.h>
#include <QMessageBox>
#include <fstream>
#include <QDir>
#include <QSpinBox>
#include "xvideo_view.h"
extern "C"
{
#include "libavutil/avutil.h"
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
}
#include <sstream>
#pragma comment(lib, "SDL2.lib")
static int sdl_width = 0;
static int sdl_height = 0;
static int pix_size = 2;
static std::ifstream yuv_file;
static XVideoView *view = NULL;
static AVFrame *frame = nullptr;
static unsigned long long file_size = 0;
static QLabel *view_fps = nullptr;
static QSpinBox *set_fps = nullptr;
static int fps = 25;
using namespace std::chrono_literals;
SdlQtRGB::SdlQtRGB(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    // 绑定渲染函数信号槽
    connect(this, &SdlQtRGB::ViewS, this, &SdlQtRGB::View);
    // 显示fps的控件
    view_fps = new QLabel(this);
    view_fps->setFixedWidth(100);
    view_fps->setText("100fps");
    set_fps = new QSpinBox(this);
    set_fps->move(200, 0);
    set_fps->setValue(25);
    set_fps->setRange(1, 300);
    auto s = qApp->applicationDirPath();
    s += "/400_300_25.yuv";
    s = QDir::toNativeSeparators(s);
    yuv_file.open(s.toStdString(), std::ios::binary);
    if (!yuv_file.is_open())
    {
        QMessageBox::warning(this, "??", "??????");
        return;
    }
    file_size = yuv_file.seekg(0, std::ios::end).tellg();
    yuv_file.seekg(0, std::ios::beg);
    sdl_width = 400;
    sdl_height = 300;
    ui.label->resize(sdl_width, sdl_height);
    view = XVideoView::Create(XVideoView::RenderType::SDL);
    view->Init(sdl_width, sdl_height,
               XVideoView::Format::YUV420P,
               (void *)ui.label->winId());
    frame = av_frame_alloc();
    frame->height = sdl_height;
    frame->width = sdl_width;
    frame->format = AV_PIX_FMT_YUV420P;
    frame->linesize[0] = sdl_width;
    frame->linesize[1] = sdl_width / 2;
    frame->linesize[2] = sdl_width / 2;
    int ret = av_frame_get_buffer(frame, 0);
    if (ret < 0)
    {
        char buf[1024];
        memset(buf, 0, sizeof(buf));
        av_strerror(ret, buf, sizeof(buf));
        QMessageBox::warning(this, "错误", buf);
        exit(1);
    }
    // startTimer(40ms);
    thread_ = std::thread(&SdlQtRGB::Main, this);
}

void SdlQtRGB::resizeEvent(QResizeEvent *ev)
{
    ui.label->resize(size());
    ui.label->move(0, 0);
    auto w = width() * ui.label->devicePixelRatio();
    auto h = height() * ui.label->devicePixelRatio();
    view->Scale(w, h);
}

SdlQtRGB::~SdlQtRGB()
{
    is_exit_ = true;
    thread_.join();
}

void SdlQtRGB::Main()
{
    while (!is_exit_)
    {
        ViewS();
        if (fps > 0)
            MSleep(1000 / fps);
        else
        {
            MSleep(40);
        }
    }
}

void SdlQtRGB::View()
{
    if (yuv_file.tellg() == file_size)
    {
        yuv_file.seekg(0, std::ios::beg);
    }
    yuv_file.read((char *)frame->data[0], sdl_width * sdl_height);     // Y
    yuv_file.read((char *)frame->data[1], sdl_width * sdl_height / 4); // U
    yuv_file.read((char *)frame->data[2], sdl_width * sdl_height / 4); // V
    if (view->IsExit())
    {
        view->Close();
        exit(0);
    }
    view->DrawFrame(frame);
    std::stringstream ss;
    ss << "fps: " << view->render_fps();
    view_fps->setText(ss.str().c_str());
    fps = set_fps->value();// 拿到播放的fps
}